from operator import itemgetter
from typing import List, Tuple, Set


def parse_accept_language(accept_language: str):
    if accept_language is None:
        return []

    locale_q_pairs: List[Tuple[str, float]] = []

    for part in accept_language.split(","):
        language = part.strip()
        lang_parts = language.split(";")
        n_lang_parts = len(lang_parts)

        if n_lang_parts == 1:
            [locale] = lang_parts
            locale_q_pairs.append((locale.strip(), 1.0))
        elif n_lang_parts == 2:
            [locale, q_str] = lang_parts
            try:
                [q, q_value] = q_str.split("=")
                assert q.strip() == "q"
            except (ValueError, AssertionError):
                continue

            locale_q_pairs.append((locale, q_value))
        else:
            continue

    locale_q_pairs.sort(key=itemgetter(0), reverse=True)

    return locale_q_pairs


def match_language(accept_language: str, my_locale: Set[str], default_locale="en-US"):
    locale_quality = parse_accept_language(accept_language)

    if len(my_locale) == 0:
        if len(locale_quality) != 0:
            return locale_quality[0][0]
        else:
            return default_locale

    for locale, _ in locale_quality:
        if locale.replace("_", "-") in my_locale:
            return locale

    return default_locale
